#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef int StackDataType;
typedef struct Stack
{
    StackDataType* data;
    int pos;
    int capacity;
}ST;

void InitStack(ST* ps)
{
    assert(ps);

    ps->data = (StackDataType*)malloc(sizeof(StackDataType) * 4);
    if (ps->data == NULL)
    {
        perror("InitStack()");
        exit(1);
    }
    ps->pos = 0;
    ps->capacity = 4;
}

void StackPush(ST* ps, StackDataType x)
{
    assert(ps);

    if (ps->pos == ps->capacity)
    {
        StackDataType* tmp = realloc(ps->data, sizeof(StackDataType) * ps->capacity * 2);
        {
            if (tmp == NULL)
            {
                perror("StackPush()");
                exit(1);
            }
            ps->data = tmp;
            ps->capacity *= 2;
        }
    }
    ps->data[ps->pos] = x;
    ps->pos++;
}

bool StackEmpty(ST* ps)
{
    assert(ps);

    return ps->pos == 0;
}

int StackSize(ST* ps)
{
    assert(ps);

    return ps->pos;
}

void StackPop(ST* ps)
{
    assert(ps);
    assert(!StackEmpty(ps));

    ps->pos--;
}

void StackDestroy(ST* ps)
{
    assert(ps);

    free(ps->data);
    ps->data = NULL;
    ps->capacity = 0;
    ps->pos = 0;
}

StackDataType StackTop(ST* ps)
{
    assert(ps);
    assert(!StackEmpty(ps));

    return ps->data[ps->pos - 1];
}

typedef struct
{
    ST PushST;
    ST PopST;
} MyQueue;


MyQueue* myQueueCreate()
{
    MyQueue* tmp = (MyQueue*)malloc(sizeof(MyQueue));
    if (tmp == NULL)
    {
        perror("myQueueCreate()");
        exit(1);
    }
    InitStack(&tmp->PushST);
    InitStack(&tmp->PopST);
    return tmp;
}

void myQueuePush(MyQueue* obj, int x)
{
    assert(obj);

    StackPush(&obj->PushST, x);
}

bool myQueueEmpty(MyQueue* obj)
{
    assert(obj);

    return StackEmpty(&obj->PushST) && StackEmpty(&obj->PopST);
}

int myQueuePeek(MyQueue* obj)
{
    assert(obj);
    assert(!myQueueEmpty(obj));

    if (StackEmpty(&obj->PopST))
    {
        while (!StackEmpty(&obj->PushST))
        {
            StackPush(&obj->PopST, StackTop(&obj->PushST));
            StackPop(&obj->PushST);
        }
    }

    return StackTop(&obj->PopST);
}

int myQueuePop(MyQueue* obj)
{
    assert(obj);
    assert(!myQueueEmpty(obj));

    myQueuePeek(obj);
    int tmp = StackTop(&obj->PopST);
    StackPop(&obj->PopST);
    return tmp;
}

void myQueueFree(MyQueue* obj)
{
    StackDestroy(&obj->PushST);
    StackDestroy(&obj->PopST);
    free(obj);
}
